#include <2025Linux.h>
// 两个线程，三个事件，更改flag的设计
typedef struct shareResource_s {
    int flag;//说明当前的事件完成状态 A --> B --> C
    // 0 A没做，可以做A 
    // 1 A做了B没做，可以做B 
    // 2 B做了C没做，可以做C
    pthread_mutex_t mutex;//为了保护flag的锁
    pthread_cond_t cond;//实现 唤醒-等待 的条件变量
} shareResource_t;
void A(){
    printf("before A\n");
    sleep(3);
    printf("after A\n");
}
void B(){
    printf("before B\n");
    sleep(3);
    printf("after B\n");
}
void C(){
    printf("before C\n");
    sleep(3);
    printf("after C\n");
}
// 主线程 A-->C
// 子线程 B
void *threadFunc(void *arg){
    // void * --> shareResource_t *
    shareResource_t * pshareRes = (shareResource_t *)arg;
    // 加锁&检查flag
    pthread_mutex_lock(&pshareRes->mutex);
    if(pshareRes->flag != 1){ // A 还没做完
        pthread_cond_wait(&pshareRes->cond,&pshareRes->mutex);
    }
    // A做完了
    pthread_mutex_unlock(&pshareRes->mutex);
    B();// 37和38的顺序：若B不需要带锁运行，则先解锁再做B，原因是临界区越短越好
    // B做完了
    pthread_mutex_lock(&pshareRes->mutex);
    pshareRes->flag = 2; // flag 1 --> 2
    pthread_cond_signal(&pshareRes->cond);
    pthread_mutex_unlock(&pshareRes->mutex);
    pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
    // 先准备共享资源
    shareResource_t shareRes;
    shareRes.flag = 0; // 最开始的时候A还没做
    pthread_mutex_init(&shareRes.mutex,NULL); // 初始化锁
    pthread_cond_init(&shareRes.cond,NULL); // 初始化条件变量
    // 创建子线程
    pthread_t tid;
    pthread_create(&tid,NULL,threadFunc,&shareRes);
    // 先A
    A();
    // A之后signal
    pthread_mutex_lock(&shareRes.mutex);
    shareRes.flag = 1; // flag 0 --> 1
    pthread_cond_signal(&shareRes.cond);
    pthread_mutex_unlock(&shareRes.mutex);

    // 准备做C
    pthread_mutex_lock(&shareRes.mutex);
    if(shareRes.flag != 2){
        pthread_cond_wait(&shareRes.cond,&shareRes.mutex);
    }
    //B做完了
    pthread_mutex_unlock(&shareRes.mutex);
    C();
    // 等待子线程终止，并回收task_struct
    pthread_join(tid,NULL);
    return 0;
}

